local major = "LegoBlock-Beta1"
local minor = tonumber(string.match("$Revision: 76$", "(%d+)") or 1)

if not LibStub then -- we don't use assert to avoid formatting a new string always :)
	error( string.format("%s requires LibStub.", major) )
end

local LegoBlock, oldRevision = LibStub:NewLibrary(major, minor)

if not LegoBlock then
	return -- no upgrade needed
end

-- Re-use or create new members.
LegoBlock.legos = LegoBlock.legos or {}
LegoBlock.restorePositions = LegoBlock.restorePositions or {}
LegoBlock.stickiedFrames = LegoBlock.stickiedFrames or {}
LegoBlock.onUpdateFuncs = LegoBlock.onUpdateFuncs or {}

-- local upvalues
local legos = LegoBlock.legos
local restorePositions = LegoBlock.restorePositions
local stickiedFrames = LegoBlock.stickiedFrames
local onUpdateFuncs = LegoBlock.onUpdateFuncs

-- fix up the frame
if not IsLoggedIn() and not LegoBlock.frame then
	LegoBlock.frame = CreateFrame("Frame")
	LegoBlock.frame:SetScript("OnEvent", function(self)
		for _, lego in pairs(legos) do
			lego:RestorePosition()
		end
		self:UnregisterEvent("PLAYER_LOGIN")
		self:SetScript("OnEvent", nil)
	end)
	LegoBlock.frame:RegisterEvent("PLAYER_LOGIN")
end

-- upgrade existing legoblocks to new function references
local methods = {"SetText", "ShowText", "SetIcon", "ShowIcon", "SetManyAttributes", "SavePosition", "RestorePosition", "SetDB"}
local OnDragStart, OnDragStop -- local functions to be declared later in the file
for _, lframe in pairs(legos) do
	lframe:SetScript("OnDragStart", OnDragStart)
	lframe:SetScript("OnDragStop", OnDragStop)
		for _, method in pairs(methods) do
		lframe[method] = LegoBlock[method]
	end
end

-- LegoBlock is now fully upgraded and normal operation can commmence.


local FlyPaper = {}
local savingPositions = {}

--[[ Positioning, code taken with permission from WindowLib by Mikk]]--
local function GetPoints(frame)
	local abs = math.abs
	local s = frame:GetScale()
	local x, y = frame:GetCenter()
	local right, left = frame:GetRight()*s, frame:GetLeft()*s
	local top, bottom = frame:GetTop()*s, frame:GetBottom()*s
	local pwidth, pheight = UIParent:GetWidth(), UIParent:GetHeight()
	x, y = x*s, y*s
	local xOff, yOff, anchor
	if left < (pwidth - right) and left < abs(x - pwidth/2) then
		xOff = left
		anchor = "LEFT"
	elseif (pwidth - right) < abs(x - pwidth/2) then
		xOff = right - pwidth
		anchor = "RIGHT"
	else
		xOff = x - pwidth/2
		anchor = ""
	end
	if bottom < (pheight - top) and bottom < abs(y - pwidth/2) then
		yOff = bottom
		anchor = "BOTTOM"..anchor
	elseif (pheight - top) < abs(y - pheight/2) then
		yOff = top - pheight
		anchor = "TOP"..anchor
	else
		yOff = y - pheight/2
	end

	if anchor == "" then
		anchor = "CENTER"
	end
	return xOff, yOff, anchor
end

-- FLYPAPER
-- Sticks frames toeachother, credit to Tuller for this
local function FrameIsDependentOnFrame(frame, otherFrame)
	if (frame and otherFrame) then
		if frame == otherFrame then return true end

		local points = frame:GetNumPoints()
		for i = 1, points do
			local parent = select(2, frame:GetPoint(i))
			if FrameIsDependentOnFrame(parent, otherFrame) then
				return true
			end
		end
	end
end

--returns true if its actually possible to attach the two frames without error
local function CanAttach(frame, otherFrame)
	if not(frame and otherFrame) then
		return
	elseif frame:GetWidth() == 0 or frame:GetHeight() == 0 or otherFrame:GetWidth() == 0 or otherFrame:GetHeight() == 0 then
		return
	elseif FrameIsDependentOnFrame(otherFrame, frame) then
		return
	end
	return true
end

local function AttachToTop(frame, otherFrame, distLeft, distRight, distCenter, offset)
	--closest to the left
	if distLeft < distCenter and distLeft < distRight then
		frame:SetPoint("BOTTOMLEFT", otherFrame, "TOPLEFT", 0, offset)
		return "TL"
	--closest to the right
	elseif distRight < distCenter and distRight < distLeft then
		frame:SetPoint("BOTTOMRIGHT", otherFrame, "TOPRIGHT", 0, offset)
		return "TR"
	--closest to the center
	else
		frame:SetPoint("BOTTOM", otherFrame, "TOP", 0, offset)
		return "TC"
	end
end

local function AttachToBottom(frame, otherFrame, distLeft, distRight, distCenter, offset)
	--bottomleft
	if distLeft < distCenter and distLeft < distRight then
		frame:SetPoint("TOPLEFT", otherFrame, "BOTTOMLEFT", 0, -offset)
		return "BL"
	--bottomright
	elseif distRight < distCenter and distRight < distLeft then
		frame:SetPoint("TOPRIGHT", otherFrame, "BOTTOMRIGHT", 0, -offset)
		return "BR"
	--bottom
	else
		frame:SetPoint("TOP", otherFrame, "BOTTOM", 0, -offset)
		return "BC"
	end
end

local function AttachToLeft(frame, otherFrame, distTop, distBottom, distCenter, offset)
	--bottomleft
	if distBottom < distTop and distBottom < distCenter then
		frame:SetPoint("BOTTOMRIGHT", otherFrame, "BOTTOMLEFT", -offset, 0)
		return "LB"
	--topleft
	elseif distTop < distBottom and distTop < distCenter then
		frame:SetPoint("TOPRIGHT", otherFrame, "TOPLEFT", -offset, 0)
		return "LT"
	--left
	else
		frame:SetPoint("RIGHT", otherFrame, "LEFT", -offset, 0)
		return "LC"
	end
end

local function AttachToRight(frame, otherFrame, distTop, distBottom, distCenter, offset)
	--bottomright
	if distBottom < distTop and distBottom < distCenter then
		frame:SetPoint("BOTTOMLEFT", otherFrame, "BOTTOMRIGHT", offset, 0)
		return "RB"
	--topright
	elseif distTop < distBottom and distTop < distCenter then
		frame:SetPoint("TOPLEFT", otherFrame, "TOPRIGHT", offset, 0)
		return "RT"
	--right
	else
		frame:SetPoint("LEFT", otherFrame, "RIGHT", offset, 0)
		return "RC"
	end
end

function FlyPaper.CanSnap(frame, otherFrame, tolerance)
	--get anchoring points
	local left = frame:GetLeft()
	local right = frame:GetRight()
	local top = frame:GetTop()
	local bottom = frame:GetBottom()
	local centerX, centerY = frame:GetCenter()

	if left and right and top and bottom and centerX then
		local oScale = otherFrame:GetScale()
		left = left / oScale
		right = right / oScale
		top = top / oScale
		bottom = bottom /oScale
		centerX = centerX / oScale
		centerY = centerY / oScale
	else return end


	local oLeft = otherFrame:GetLeft()
	local oRight = otherFrame:GetRight()
	local oTop = otherFrame:GetTop()
	local oBottom = otherFrame:GetBottom()
	local oCenterX, oCenterY = otherFrame:GetCenter()

	if oLeft and oRight and oTop and oBottom and oCenterX then
		local scale = frame:GetScale()
		oCenterX = oCenterX / scale
		oCenterY = oCenterY / scale
		oLeft = oLeft / scale
		oRight = oRight / scale
		oTop = oTop / scale
		oBottom = oBottom / scale
	else return end


	--[[ Start Attempting to Anchor <frame> to <otherFrame> ]]--

	if(oLeft - tolerance <= left and oRight + tolerance >= right) or (left - tolerance <= oLeft and right + tolerance >= oRight)then
		if( math.abs(oTop - bottom) <= tolerance or math.abs(oBottom - top) <= tolerance ) then
			return true
		end
	end


	if(oTop + tolerance >= top and oBottom - tolerance <= bottom) or (top + tolerance >= oTop and bottom - tolerance <= oBottom)then
		if( math.abs(oLeft - right) <= tolerance or math.abs(oRight - left) <= tolerance ) then
			return true
		end
	end
end

function FlyPaper.Stick(frame, otherFrame, tolerance, xOff, yOff)
	if not xOff then xOff = 0 end
	if not yOff then yOff = 0 end

	if not CanAttach(frame, otherFrame) then return end

	--get anchoring points
	local left = frame:GetLeft()
	local right = frame:GetRight()
	local top = frame:GetTop()
	local bottom = frame:GetBottom()
	local centerX, centerY = frame:GetCenter()

	if left and right and top and bottom and centerX then
		local oScale = otherFrame:GetScale()
		left = left / oScale
		right = right / oScale
		top = top / oScale
		bottom = bottom /oScale
		centerX = centerX / oScale
		centerY = centerY / oScale
	else return end


	local oLeft = otherFrame:GetLeft()
	local oRight = otherFrame:GetRight()
	local oTop = otherFrame:GetTop()
	local oBottom = otherFrame:GetBottom()
	local oCenterX, oCenterY = otherFrame:GetCenter()

	if oLeft and oRight and oTop and oBottom and oCenterX then
		local scale = frame:GetScale()
		oCenterX = oCenterX / scale
		oCenterY = oCenterY / scale
		oLeft = oLeft / scale
		oRight = oRight / scale
		oTop = oTop / scale
		oBottom = oBottom / scale
	else return end


	--[[ Start Attempting to Anchor <frame> to <otherFrame> ]]--

	if(oLeft - tolerance <= left and oRight + tolerance >= right) or (left - tolerance <= oLeft and right + tolerance >= oRight)then
		local distCenter = math.abs(oCenterX - centerX)
		local distLeft = math.abs(oLeft - left)
		local distRight = math.abs(right - oRight)

		--try to stick to the top if the distance is under the threshold distance to stick frames to each other (tolerance)
		if math.abs(oTop - bottom) <= tolerance then
			frame:ClearAllPoints()
			return AttachToTop(frame, otherFrame, distLeft, distRight, distCenter, yOff)
		--to the bottom
		elseif math.abs(oBottom - top) <= tolerance then
			frame:ClearAllPoints()
			return AttachToBottom(frame, otherFrame, distLeft, distRight, distCenter, yOff)
		end
	end


	if(oTop + tolerance >= top and oBottom - tolerance <= bottom) or (top + tolerance >= oTop and bottom - tolerance <= oBottom)then
		local distCenter = math.abs(oCenterY - centerY)
		local distTop = math.abs(oTop - top)
		local distBottom = math.abs(oBottom - bottom)

		--to the left
		if math.abs(oLeft - right) <= tolerance then
			frame:ClearAllPoints()
			return AttachToLeft(frame, otherFrame, distTop, distBottom, distCenter, xOff)
		end

		--to the right
		if math.abs(oRight - left) <= tolerance then
			frame:ClearAllPoints()
			return AttachToRight(frame, otherFrame, distTop, distBottom, distCenter, xOff)
		end
	end
end

function FlyPaper.StickToPoint(frame, otherFrame, point, xOff, yOff)
	if( not frame or not otherFrame or FrameIsDependentOnFrame(otherFrame, frame) ) then
		return
	end

	if( not xOff ) then xOff = 0 end
	if( not yOff ) then yOff = 0 end

	frame:ClearAllPoints()

	--to the top
	if point == "TL" then
		frame:SetPoint("BOTTOMLEFT", otherFrame, "TOPLEFT", 0, yOff)
		return point
	elseif point == "TC" then
		frame:SetPoint("BOTTOM", otherFrame, "TOP", 0, yOff)
		return point
	elseif point == "TR" then
		frame:SetPoint("BOTTOMRIGHT", otherFrame, "TOPRIGHT", 0, yOff)
		return point
	end

	--to the bottom
	if point == "BL" then
		frame:SetPoint("TOPLEFT", otherFrame, "BOTTOMLEFT", 0, -yOff)
		return point
	elseif point == "BC" then
		frame:SetPoint("TOP", otherFrame, "BOTTOM", 0, -yOff)
		return point
	elseif point == "BR" then
		frame:SetPoint("TOPRIGHT", otherFrame, "BOTTOMRIGHT", 0, -yOff)
		return point
	end

	--to the left
	if point == "LB" then
		frame:SetPoint("BOTTOMRIGHT", otherFrame, "BOTTOMLEFT", -xOff, 0)
		return point
	elseif point == "LC" then
		frame:SetPoint("RIGHT", otherFrame, "LEFT", -xOff, 0)
		return point
	elseif point == "LT" then
		frame:SetPoint("TOPRIGHT", otherFrame, "TOPLEFT", -xOff, 0)
		return point
	end

	--to the right
	if point == "RB" then
		frame:SetPoint("BOTTOMLEFT", otherFrame, "BOTTOMRIGHT", xOff, 0)
		return point
	elseif point == "RC" then
		frame:SetPoint("LEFT", otherFrame, "RIGHT", xOff, 0)
		return point
	elseif point == "RT" then
		frame:SetPoint("TOPLEFT", otherFrame, "TOPRIGHT", xOff, 0)
		return point
	end
end

-- START LEGO BLOCK CODE
-- Misc stuffs
local protDefaults = {
	width = 8,
	height = 32,
	bg = {
		bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
		edgeSize = 16,
		insets = {left = 4, right = 4, top = 4, bottom = 4},
	},
}

local defTbl = setmetatable({}, {
	__index = function(t,k) return protDefaults[k] end,
	__newindex = function(t,k,v) end, -- Don't allow saves to the default table
})

local function resetFramePosition(frame)
	-- If someone is positioned to us, reset their position to prevent issues
	--[[for stickFrame, stuckTo in pairs(stickiedFrames) do
		if( stuckTo == frame ) then
			resetFramePosition(stickFrame)
			stickiedFrames[stickFrame] = nil
			break
		end
	end]]--

	--Debug( "Reset position " .. frame:GetName() )
	-- ChatFrame1:AddMessage("Reset position: "..frame:GetName())

	local xOff, yOff, anchor = GetPoints(frame)

	frame.stickPoint = nil

	frame:ClearAllPoints()
	frame:SetPoint(anchor or "CENTER", UIParent, anchor or "CENTER", xOff, yOff)
	frame:SavePosition()
end

local xOff = -4
local yOff = -4
local tolerance = 10

local function savePositions(frame)
	if savingPositions[stuckFrame] then return end
	for stuckFrame, freeFrame in pairs(stickiedFrames) do
		if freeFrame == frame then
			savingPositions[stuckFrame] = true
			savePositions(stuckFrame)
		end
	end
	frame:SavePosition()
end

-- reverse the SetPoint connections (it's a silly linked list)
-- means we can do it iteratively
-- pass in the original node
local function reverseStick(block)
	-- if there is no next block then return
	if( not stickiedFrames[block] ) then return end
	local prevBlock = nil
	while block do
		local nextBlock = stickiedFrames[block]
		if prevBlock then
			prevBlock:ClearAllPoints()
			local snap = FlyPaper.StickToPoint(block, prevBlock, point, xOff, yOff)
			if snap then
				block.stickPoint = snap
				prevBlock.stickPoint = stickiedFrames[prevBlock] and stickiedFrames[prevBlock].stickPoint
			end
		end
		stickiedFrames[block] = prevBlock
		prevBlock = block
		block = nextBlock
		local point
		if prevBlock.stickPoint then
			point = string.sub(prevBlock.stickPoint, 0, 1)
			if( point == "T" ) then
				point = "B" .. string.sub(prevBlock.stickPoint, 2)
			elseif( point == "B" ) then
				point = "T" .. string.sub(prevBlock.stickPoint, 2)
			elseif( point == "L" ) then
				point = "R" .. string.sub(prevBlock.stickPoint, 2)
			elseif( point == "R" ) then
				point = "L" .. string.sub(prevBlock.stickPoint, 2)
			end
		end
		prevBlock.stickPoint = point
	end
	block = prevBlock
	while block do
		local nextBlock = stickiedFrames[block]
		if nextBlock then
			block.stickPoint = nextBlock.stickPoint
			local snap = FlyPaper.StickToPoint(block, nextBlock, block.stickPoint, xOff, yOff)
			block.stickPoint = snap
		end
		block = nextBlock
	end
end

-- Actually move
--local updateCount = 0
--local startCounting
local function frameMoving(self)
	local x,y = GetCursorPosition()
	local s = self:GetEffectiveScale()


	-- CTRL DOWN
	-- Reset anything linked to us or we're linked to
	if( self.ctrlDown ) then
		self:ClearAllPoints()
		self:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x / s, y / s)
	else

		-- clear all the points then set it to its current position relative to
		-- UIParent.  This allows FlyPaper to do its magic without any
		-- dependencies on other LegoBlock blocks
		self:ClearAllPoints()
		self:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x / s, y / s)

		--if( startCounting ) then
		--	updateCount = updateCount + 1
		--	if( updateCount >= 2 ) then
		--		startCounting = nil
		--		updateCount = 0
		--
		--		self:StartMoving()
		--	end
		--end

		local stick
		for _, frame in pairs(legos) do
			stick = FlyPaper.Stick(self, frame, tolerance, xOff, yOff)

			if( stick and not self.stickPoint ) then
				self.stickPoint = stick
				stickiedFrames[self] = frame

				--startCounting = true
				--self:StopMovingOrSizing()

				-- Figure out if we need to restick any frames closeby
				for _, subFrame in pairs(legos) do
					local subStick = FlyPaper.Stick(subFrame, self, tolerance, xOff, yOff)

					if( subStick ) then
						stickiedFrames[subFrame] = self
						subFrame.stickPoint = subStick
						subFrame:SavePosition()
						break
					end
				end
				break
			end
		end

		if( self.stickPoint and ( not stickiedFrames[self] or not FlyPaper.CanSnap(self, stickiedFrames[self], tolerance) ) ) then
			resetFramePosition(self)
			stickiedFrames[self] = nil
		end
	end
end

function OnDragStart(frame)
	if( InCombatLockdown() or ( frame.optionsTbl and frame.optionsTbl.locked ) ) then return end

	onUpdateFuncs[frame] = frame:GetScript("OnUpdate")

	frame.ctrlDown = IsControlKeyDown()
	if frame.ctrlDown then
		local self = frame
		-- Unlink the frame stuck to us (if any)
		for frame, stuckTo in pairs(stickiedFrames) do
			if( stuckTo == self ) then
				resetFramePosition(frame)
				stickiedFrames[frame] = nil
			end
		end

		if( stickiedFrames[self] ) then
			-- Unlink us from what we're stuck to
			resetFramePosition(self)
			stickiedFrames[self] = nil
		end
	end
	frame.isMoving = true
	--frame:SetMovable(true)
	--frame:StartMoving()
	if( stickiedFrames[frame] ) then
		reverseStick(frame)
	end

	frame:SetScript("OnUpdate", frameMoving)
end

function OnDragStop(frame)
	if( InCombatLockdown() or not frame.isMoving ) then return end

	frame:SetScript("OnUpdate", onUpdateFuncs[frame])
	--frame:StopMovingOrSizing()
	frame:SavePosition()

	for stuckFrame, freeFrame in pairs(stickiedFrames) do
		if freeFrame == frame then
			savingPositions[stuckFrame] = true
			savePositions(stuckFrame)
		end
	end
	for k,v in pairs(savingPositions) do savingPositions[k] = nil end

	--frame:SetMovable(false)
	frame.isMoving = false
end

local function resizeWindow(self, noResize)
	if( noResize or self.optionsTbl.noResize or InCombatLockdown() ) then
		return
	end
	
	-- Base frame width.
	local width = self.optionsTbl.width or defTbl.width
	
	-- Add backdrop width.
	if( self.optionsTbl.bg ~= false ) then
		local bg = self.optionsTbl.bg or defTbl.bg
		width = width + bg.insets.left + bg.insets.right
	end
	
	if( self.optionsTbl.showIcon ) then
		width = width + self.Icon:GetWidth()
	end

	if( self.optionsTbl.showText ) then
		local textWidth = self.Text:GetStringWidth()
		self.Text:SetWidth(textWidth)
		width = width + textWidth
	end
	
	self:SetWidth(width)
end

-- LEGOBLOCK LIBRARY
function LegoBlock:New(name, text, icon, optionsTbl)
	optionsTbl = optionsTbl or defTbl
	if( optionsTbl.savedFields ) then
		local savedFields = optionsTbl.savedFields
		for i=1, #(savedFields) , 2 do
			local key, val = savedFields[i], savedFields[i+1]
			if( not key ) then break end

			frame[key] = val
		end
	end

	local width = optionsTbl.width or defTbl.width
	local height = optionsTbl.height or defTbl.height
	local bg = optionsTbl.bg
	if bg == false then
		bg = nil -- when someone passes bg as false nil it out for SetBackDrop
	elseif not bg then bg = defTbl.bg end -- if bg is nil use the defTbl.

	local frame = CreateFrame("Button", "Lego" .. name, UIParent, "SecureActionButtonTemplate")
	frame:SetWidth(width)
	frame:SetHeight(height)
	frame:EnableMouse(true)
	frame:RegisterForDrag("LeftButton")
	frame:SetClampedToScreen(true)

	frame.Icon = frame:CreateTexture()
	frame.Icon:SetHeight(16)
	frame.Icon:SetWidth(16)
	frame.Icon:SetPoint("LEFT", frame, "LEFT", 8, 0)

	frame.Text = frame:CreateFontString(nil, nil, "GameFontNormal")
	frame.Text.positionType = "none"

	frame:SetBackdrop(bg)
	frame:SetBackdropColor(0,0,0,0.3)
	frame:SetBackdropBorderColor(0,0,0,0.7)
	frame:SetScript("OnDragStart", OnDragStart)
	frame:SetScript("OnDragStop", OnDragStop)
	frame.legoID = #(legos) + 1

	-- Inject methods
	for _, method in pairs(methods) do
		frame[method] = LegoBlock[method]
	end

	-- Setup
	frame:SetDB(optionsTbl)
	frame:SetText(text, true)
	frame:ShowText(optionsTbl.showText, true)

	frame:SetIcon(icon)
	frame:ShowIcon(optionsTbl.showIcon, true)

	resizeWindow(frame)

	table.insert(legos, frame)
	return frame
end

function LegoBlock.SavePosition(self)
	local x, y, anchor = GetPoints(self)

	self.optionsTbl.x = x
	self.optionsTbl.y = y
	self.optionsTbl.anchor = anchor
	self.optionsTbl.scale = self:GetScale()

	local relative = select(2, self:GetPoint())
	if( self.stickPoint and relative and relative:GetName() ~= "UIParent" ) then
		self.optionsTbl.stickPoint = self.stickPoint
		self.optionsTbl.relative = relative:GetName()
	else
		self.optionsTbl.stickPoint = nil
		self.optionsTbl.relative = nil
	end
end

function LegoBlock.RestorePosition(self)
	if not IsLoggedIn() then return end

	self:ClearAllPoints()

	local scale = self.optionsTbl.scale
	if( scale ) then
		self:SetScale(scale)
	else
		scale = self:GetScale()
	end

	local posFrame = getglobal(self.optionsTbl.relative)
	-- Once the frame we want loads, reposition us
	if( not posFrame and self.optionsTbl.stickPoint ) then
		restorePositions[self] = self.optionsTbl.relative
	end

	if( self.optionsTbl.stickPoint and posFrame ) then
		local stuck = FlyPaper.StickToPoint(self, posFrame, self.optionsTbl.stickPoint)

		if( stuck ) then
			self.stickPoint = self.optionsTbl.stickPoint
			stickiedFrames[self] = posFrame
		end
	else
		local x = 0
		if( self.optionsTbl.x ) then
			x = self.optionsTbl.x / scale
		end

		local y = 0
		if( self.optionsTbl.y ) then
			y = self.optionsTbl.y / scale
		end

		self:SetPoint(self.optionsTbl.anchor or "CENTER", UIParent, self.optionsTbl.anchor or "CENTER", x, y)
	end
end

function LegoBlock.SetManyAttributes(self, ...)
	for i=1, select("#", ...) , 2 do
		local key, val = select(i, ...)
		if( not key ) then return end
		self:SetAttribute(key, val)
	end
end

function LegoBlock.SetText(self, text, noResize)
	self.Text:SetText(text)
	resizeWindow(self, noResize)
end

function LegoBlock.ShowText(self, show, noResize)
	self.optionsTbl.showText = show

	if( show ) then
		self.Text:Show()
	else
		self.Text:Hide()
	end

	resizeWindow(self, noResize)
end

-- Sets the icon texture
function LegoBlock.SetIcon(self, icon)
	self.Icon:SetTexture(icon)
end

-- Show/hide the icon
function LegoBlock.ShowIcon(self, show, noResize)
	self.optionsTbl.showIcon = show

	if( self.optionsTbl.showIcon ) then
		self.Icon:Show()
	else
		self.Icon:Hide()
	end

	if( not show and self.Text.positionType ~= "text" ) then
		self.Text.positionType = "text"
		self.Text:ClearAllPoints()
		self.Text:SetJustifyH("CENTER")
		self.Text:SetPoint("CENTER", 0, 0)

	elseif( show and self.Text.positionType ~= "icon" ) then
		self.Text.positionType = "icon"
		self.Text:ClearAllPoints()
		self.Text:SetJustifyH("LEFT")
		self.Text:SetPoint("LEFT", self.Icon, "RIGHT", 0, 0)
	end

	resizeWindow(self, noResize)
end

function LegoBlock.SetDB(self, db)
	self.optionsTbl = db

	self:SetWidth(db.width or defTbl.width)
	self:SetHeight(db.height or defTbl.height)

	if( db.showText ) then
		self.Text:Show()
	else
		self.Text:Hide()
	end

	if( db.hidden ) then
		self:Hide()
	else
		self:Show()
	end

	self:ShowIcon(self.optionsTbl.showIcon, true)

	resizeWindow(self)
	self:RestorePosition()

	-- Figure out if we need to position anyone to us
	for frame, posName in pairs(restorePositions) do
		if( posName == self:GetName() ) then
			frame:RestorePosition()
			restorePositions[frame] = nil
		end
	end
end